package com.erp.Struts.Action;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import com.erp.Struts.common.Constants;
import com.erp.hibernate.beans.Employee;
import com.erp.hibernate.beans.Menu;
import com.erp.hibernate.dao.EmployeeDAO;
import com.erp.hibernate.dao.MenuDAO;
import com.erp.hibernate.dao.RoleDAO;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;

public class LoginAction extends ActionSupport {

	private static final long serialVersionUID = -4342363293489120646L;
	private EmployeeDAO employeeDAO;
	private String username;
	private String password;
	private RoleDAO roleDAO;
	private MenuDAO menuDAO;
	
	public void validate() {
		clearErrorsAndMessages();
	}

	public String login() throws Exception {
		clearErrorsAndMessages();
		Employee em = this.employeeDAO.getEmployee(username, password);
		if (em != null) {
			if(em.getEnabled().intValue() == 0){
				super.addActionError(super.getText("该用户已被注销"));
				return Action.INPUT;
			}else{
				Menu authRoot = getMenuByRoleId(em.getRole().getId());
				ActionContext.getContext().getSession().put("root", authRoot);
				ActionContext.getContext().getSession().put(Constants.USERNAME_KEY,
						username);
				ActionContext.getContext().getSession().put(Constants.EMPLOYEE_KEY,
						em);
				return Action.SUCCESS;
			}
		} else {
			super.addActionError(super.getText("用户或密码错误"));
			return Action.INPUT;
		}
	}
	
	private Menu getMenuByRoleId(int roleId) {
		Menu[] menus = roleDAO.getMenus(roleId);

		if (menus==null||menus.length==0) return null;
		
		//建立权限允许的菜单

			Menu authRoot=new Menu();
			authRoot.setMenu(null);
			authRoot.setName("-授权的菜单-");
			authRoot.setUrl("#");
			authRoot.setMenus(new HashSet(0));
			authRoot.setId(1);
			
			//从ROOT开始遍历所有节点
			Menu root = this.menuDAO.getMenu(1);
			
			for (Object child : root.getMenus()) {
				Menu childMenu = (Menu) child;
				for (Object leaf : childMenu.getMenus()) {
					Menu leafMenu = (Menu) leaf;
					if (!leafMenu.getMenus().isEmpty()) {
						for (Object tip : leafMenu.getMenus()) {
							Menu tipMenu = (Menu) tip;
							//tipMenu是包含有功能的叶子节点
							if (this.isMenuAuth(menus,tipMenu)){//如果授权就加入到授权树中
								this.addMenu(authRoot, tipMenu, 3);
							}					
						}
					}else{
						//leafMenu是包含有功能的叶子节点
						if (this.isMenuAuth(menus,leafMenu)){//如果授权就加入到授权树中
							this.addMenu(authRoot, leafMenu, 2);
						}
					}
				}
			}
		return authRoot;
	}
	
	private boolean isMenuAuth(Menu[] authMenus,Menu menu){
		for (int i=0;i<authMenus.length;i++){
			if (authMenus[i].getId().intValue()==menu.getId().intValue()){
				return true;
			}
		}
		return false;
	}
	
	private boolean compare(Set menuroot, Menu menu){
		Iterator<Menu> root = menuroot.iterator();
		while(root.hasNext()){
			Menu point = (Menu)root.next();
			if(point.getName().equals(menu.getName())){
				return true;
			}
		}
		return false;
	}
	
	private void addMenu(Menu root,Menu menu,int level){
		Menu firstMenu=null;
		if (level==2){//二级节点
			firstMenu=menu.getMenu();
            if (compare(root.getMenus(),firstMenu)){//该节点已经存在
            	//找到该节点并将子节点插入
            	for (Object child:root.getMenus()){
            		if (((Menu)child).getName().equals(menu.getMenu().getName())){
            			((Menu)child).getMenus().add(menu);
            			break;
            		}
            	}
    		}else{//该节点不存在
 			   Menu newMenu=new Menu();
 			   newMenu.setName(menu.getMenu().getName());
 			   newMenu.setId(menu.getMenu().getId());
 			   newMenu.setMenu(root);
 			   newMenu.setMenus(new HashSet(0));
 			   menu.setMenu(newMenu);
 			   newMenu.getMenus().add(menu);
 			   root.getMenus().add(newMenu);
    		}
 		}
		/*=============================================================*/

		if (level==3){//三级节点
 			firstMenu=menu.getMenu().getMenu();
            
 			if (compare(root.getMenus(),firstMenu)){//该节点已经存在
            	//找到该节点
            	for (Object child:root.getMenus()){
            		if (((Menu)child).getName().equals(menu.getMenu().getMenu().getName())){
            			firstMenu=(Menu)child;
            			break;
            		}
            	}
    		}else{//该节点不存在,则插入该节点
 			   Menu newMenu=new Menu();
 			   newMenu.setName(menu.getMenu().getMenu().getName());
 			   newMenu.setId(menu.getMenu().getMenu().getId());
 			   newMenu.setMenu(root);
 			   newMenu.setMenus(new HashSet(0));
 			   root.getMenus().add(newMenu);
 			   firstMenu=newMenu;
    		}
            
            //把本节点以及父节点插入到一级节点下
            if (compare(firstMenu.getMenus(),menu.getMenu())){//该节点的父节点已经存在
            	//找到该父节点
            	for (Object child:firstMenu.getMenus()){
            		if (((Menu)child).getName().equals(menu.getMenu().getName())){
            			((Menu)child).getMenus().add(menu);//插入
            			break;
            		}
            	}
    		}else{//该父节点不存在,则插入该父节点和子节点
 			   Menu newMenu=new Menu();
 			   newMenu.setName(menu.getMenu().getName());
 			   newMenu.setUrl(menu.getMenu().getUrl());
 			   newMenu.setId(menu.getMenu().getId());
 			   newMenu.setMenu(firstMenu);
 			   newMenu.setMenus(new HashSet(0));
 			   menu.setMenu(newMenu);
 			   newMenu.getMenus().add(menu);
 			   firstMenu.getMenus().add(newMenu);
    		}      
 		}
	}
	
	public EmployeeDAO getEmployeeDAO() {
		return employeeDAO;
	}
	public void setEmployeeDAO(EmployeeDAO employeeDAO) {
		this.employeeDAO = employeeDAO;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public RoleDAO getRoleDAO() {
		return roleDAO;
	}

	public void setRoleDAO(RoleDAO roleDAO) {
		this.roleDAO = roleDAO;
	}

	public MenuDAO getMenuDAO() {
		return menuDAO;
	}

	public void setMenuDAO(MenuDAO menuDAO) {
		this.menuDAO = menuDAO;
	}
}
